﻿Function Get-TargetResource
{
    # TODO: Add parameters here
    # Make sure to use the same parameters for
    # Get-TargetResource, Set-TargetResource, and Test-TargetResource
    param(
    	[parameter(Mandatory = $true)]
		[System.String]
		$XPath,
		[parameter(Mandatory = $true)]
        [System.String]
		$XAttributes,
        [ValidateSet("Present","Absent")]
	    [System.String]
	    $Ensure,
		[parameter(Mandatory = $true)]
		[System.String]
		$File,
        [parameter(Mandatory = $false)]
        [boolean]
        $NotMatch=$false
    )
}

Function Set-TargetResource
{
    # TODO: Add parameters here
    # Make sure to use the same parameters for
    # Get-TargetResource, Set-TargetResource, and Test-TargetResource
    param(
    	[parameter(Mandatory = $true)]
		[System.String]
		$XPath,
		[parameter(Mandatory = $true)]
        [System.String]
		$XAttributes,
        [ValidateSet("Present","Absent")]
	    [System.String]
	    $Ensure,
		[parameter(Mandatory = $true)]
		[System.String]
		$File,
        [parameter(Mandatory = $false)]
        [boolean]
        $NotMatch=$false
    )

    [System.Xml.XmlDocument]$xml=loadxmlfile($File)
    #Inititalise values
	[System.Xml.XmlElement]$node = $null
	
    $XAttribute = ConvertFrom-StringData -StringData $XAttributes

	$nodes = $xml.SelectNodes($XPath)
	Write-Verbose "$($nodes.Count) nodes were found that matched the XPath criteria"
    write-debug "Looping through all the nodes found with the XPath string, ""$XPath"""

	foreach ($node in $nodes)
	{
        write-debug "Node name is ""$($node.LocalName)"""
		foreach ($attribute in $XAttribute)
		{
			
			$value = $null
            write-debug "The Attribute key to locate is ""$($attribute.Keys)"""
            Write-Debug "The Attribute key value to locate is ""$($attribute.values)"""
			if ($node.HasAttribute($attribute.Keys) -eq $true)
			{
			    $value = $node.GetAttribute($attribute.Keys)
                Write-Debug "The value found for the identifying attribute is ""$value"""
                write-debug "NotMatchValue is $NotMatch"
                if ($NotMatch -eq $false)
                {
                    write-verbose "Checking that the key ""$($attribute.keys)"" has a value"
                    #[string]$attributevalues = $attribute.Values
				    if ($value.ToLower() -eq $attribute.values.ToLower())
				    {
					    Write-Debug "The node ""$($node.LocalName)"" has an attribute ""$($attribute.Keys)"" that has a matching value ""$value"""
					    Write-Verbose "Found an attribute with matching values."
                        if ($Ensure -eq "Absent")
                        {
                            #Remove Attribute
                            write-verbose "Removing the key ""$($attribute.Keys)"" from the node ""$($node.LocalName)"""
                            $node.RemoveAttribute($attribute.Keys)
                        }
                        
				    }
				    else
				    {
					    
					    Write-Verbose "Found an attribute without a matching value."
					    Write-Debug "The value to find ""$($attribute.values)"" in the key ""$($attribute.Keys)"" does not match the found value of ""$value"""
                        
                        if ($Ensure -eq "Present")
                        {
                            #Set attribute value
                            write-verbose "Changing the value of ""$($attribute.keys)"" to ""$attribute.values"""
                            $node.SetAttribute($attribute.Keys,$attribute.Values)
                         
                            
                        }
				    }
                }
                else
                {
                    write-verbose "Not checking that the key ""$($attribute.keys)"" has a value"
                    if ($Ensure -eq "Absent")
                    {
                        #Remove Attribute
                        write-verbose "Removing the key ""$($attribute.Keys)"" from the node ""$($node.LocalName)"""
                        $node.RemoveAttribute($attribute.Keys)
                    }
                }
			}
			else
			{
				Write-Debug "The key ""$($attribute.Keys)"" to locate is not found in the node ""$($node.LocalName)"""
                
                if ($Ensure -eq "Present")
                {
                    Write-Verbose "Adding the attribute ""$($attribute.Keys)"" with the value $attribute.values to the node ""$($node.LocalName)"""
                    #Add the attribute and value into the node
                    $node.SetAttribute($attribute.Keys,$attribute.Values)

                }
                else
                {
                    Write-Debug "The setting for Ensure is $Ensure so there is nothing to change with the attribute ""$($attribute.Keys)"" in this node ""$($node.LocalName)"""
                }
			}
		}
		
	}
    $xml.Save($File)

}

Function Test-TargetResource
{
	# TODO: Add parameters here
	# Make sure to use the same parameters for
	# Get-TargetResource, Set-TargetResource, and Test-TargetResource
    [OutputType([Boolean])]
	param (
		[parameter(Mandatory = $true)]
		[System.String]
		$XPath,
		[parameter(Mandatory = $true)]
        [System.String]
		$XAttributes,
		[ValidateSet("Present", "Absent")]
		[System.String]
		$Ensure,
		[parameter(Mandatory = $true)]
		[System.String]
		$File,
        [parameter(Mandatory = $false)]
        [boolean]
        $NotMatch=$false
        
	)

    [System.Xml.XmlDocument]$xml=loadxmlfile($File)
    
    #Inititalise values
	[System.Xml.XmlElement]$node = $null
	$match = 0
	$nomatch = 0
	$XAttribute = ConvertFrom-StringData -StringData $XAttributes

	$nodes = $xml.SelectNodes($XPath)
	Write-Verbose "$($nodes.Count) nodes were found that matched the XPath criteria"
    write-debug "Looping through all the nodes found with the XPath string, ""$XPath"""

	foreach ($node in $nodes)
	{
        write-debug "Node name is ""$($node.LocalName)"""
        #Loop through all the key pairs defined in $Xttributes
		foreach ($attribute in $XAttribute)
		{
			$value=$null

            write-debug "The Attribute key to locate is ""$($attribute.Keys)"""
            Write-Debug "The Attribute key value to locate is ""$($attribute.values)"""

			if ($node.HasAttribute($attribute.Keys) -eq $true)
			{
			    $value = $node.GetAttribute($attribute.Keys)
                Write-Debug "The value found for the identifying attribute is ""$value"""
                write-debug "NotMatchValue is $NotMatch"
                if ($NotMatch -eq $false)
                {
                    write-verbose "Checking that the key ""$($attribute.keys)"" has a value"
                    
				    if ($value -eq $attribute.values)
				    {
					    Write-Debug "The node ""$($node.LocalName)"" has an attribute ""$($attribute.Keys)"" that has a matching value ""$value"""
					    $match += 1
					    Write-Verbose "Found $match attributes with matching values."
				    }
				    else
				    {
					    $nomatch += 1
					    Write-Verbose "Found $($nomatch) attributes without matching values."
					    Write-Debug "The value to find ""$($attribute.values)"" in the key ""$($attribute.Keys)"" does not match the found value of ""$value"""
				    }
                }
                else
                {
                    write-verbose "Not checking that the key ""$($attribute.keys)"" has a value"
                }
			}
			else
			{
				$nomatch += 1
				Write-Debug "The key ""$($attribute.Keys)"" to locate is not found in the node ""$($node.LocalName)"""
				Write-Verbose "There are $nomatch attributes that do not exist"
			}
		}
		
	}

	If ($Ensure -eq "Present")
	{
		if ($nomatch -gt 0) 
        { 
            write-Verbose "One or more nodes have missing or incorrect attributes and Ensure=Present"
            write-debug "Number of nodes with missing attribute = $nomatch"
            write-debug "Number of nodes with matching attribute = $match"
            return $false 
        }
		else 
        {
            write-verbose "No nodes have missing or incorrect attributes Ensure = Present"
            write-debug "Number of nodes with missing attribute = $nomatch"
            write-debug "Number of nodes with matching attribute = $match"
            return $true 
        }
	}
	else
	{
		if ($nomatch -gt 0) 
        {
            write-Verbose "One or more nodes have missing or incorrect attributes and Ensure = Absent"
            write-debug "Number of nodes with missing attribute = $nomatch"
            write-debug "Number of nodes with matching attribute = $match"
            return $true 
        }
		else 
        {
            write-verbose "No nodes have missing or incorrect attributes and Ensure = Absent"
            write-debug "Number of nodes with missing attribute = $nomatch"
            write-debug "Number of nodes with matching attribute = $match"
            return $false 
        }
	}
    $xml.Save($File)
}

#Initialises the XML variable properly to manage XML documents that define a DTD file.
Function loadxmlfile
{

param
(
    [parameter(Mandatory = $true)]
    [System.String]
	$File
)

    $xml = New-Object System.Xml.XmlDocument
    $xml.XmlResolver = $null
    Write-Verbose "Loading file $File"
	$xml.Load($File)
    return $xml

}


Export-ModuleMember -Function *-TargetResource